//
//  PTRecording.swift
//  PointTest28
//
//  Created by sc-chen on 2023/6/26.
//

import SwiftUI
import AVFoundation

struct PTRecording: View {
    
    @State private var isShowingHUD = false
    @State private var detailTxt = "不支持开发功能"
    
    // 录音状态, false表示未录音，true表示正在录音
    @State private var isRecording = false
    
    // 录音计时器
    @State private var recordingTime: TimeInterval = 0.0
    private let timerInterval = 0.01
    @State private var timer: Timer? = nil
    
    @State private var filePath = ""
    
    // 录音机
    private let audioRecorder = try? AVAudioRecorder(url: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("recording.caf"), settings: [
        AVFormatIDKey: Int(kAudioFormatLinearPCM),
        AVSampleRateKey: 44100.0,
        AVNumberOfChannelsKey: 2,
        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ])
    
    @State private var aup: AVAudioPlayer?
    @State var isPlaying = false
    
    var body: some View {
        ZStack {
            VStack {
                ScrollView {
                    Text(timeString(recordingTime))
                        .font(.system(size: 30))
                        .foregroundColor(isRecording ? .red : .white)
                        .padding()
                    
                    Button(action: {
                        if self.isRecording {
                            stopRecording()
                        } else {
                            startRecording()
                        }
                    }) {
                        Text(self.isRecording ? "AVAudioRecorder\n停止录音" : "AVAudioRecorder\n开始录音")
                            .font(.system(size: 13))
                            .foregroundColor(.white)
                            .frame(maxWidth: .infinity)
                            .background(
                                RoundedRectangle(cornerRadius: 25)
                                    .fill(Color.green)
                            )
                    }
                    .buttonStyle(.borderless)
                    .padding()
                    
                    Text("AudioRecord录音位置：\(filePath)")
                        .font(.system(size: 12))
                        .padding()
                    
                    Button(action: {
                        print("点击AVAudioPlayer播放")
                        if self.isPlaying {
                            stopPlayback()
                        } else {
                            playRecording()
                        }
                    }) {
                        Text(self.isPlaying ? "AVAudioPlayer停止播放" : "AVAudioPlayer播放")
                            .font(.system(size: 13))
                            .padding(.top,10)
                            .padding(.bottom,10)
                            .foregroundColor(.white)
                            .frame(maxWidth: .infinity,maxHeight: 40)
                            .background(
                                RoundedRectangle(cornerRadius: 25)
                                    .fill(Color.blue)
                            )
                    }
                    .buttonStyle(.plain)
                }
            }
            PTProgressHud(isPresented: $isShowingHUD, text: $detailTxt)
        }.onDisappear(){
            deleteAudioFile()
            stopPlayback()
        }.onAppear(){
            do {
                try AVAudioSession.sharedInstance().setCategory(.playAndRecord)
                try AVAudioSession.sharedInstance().setActive(true)
                audioRecorder?.prepareToRecord()
            } catch {
                print("Failed to start recording: \(error.localizedDescription)")
            }
        }
    }
    private func showHud(text: String) {
        isShowingHUD = true
        detailTxt = text
        DispatchQueue.main.asyncAfter(deadline: .now()+2){
            isShowingHUD = false
        }
    }
    
    func deleteAudioFile() {
        let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("recording.caf")
        try? FileManager.default.removeItem(at: url)
    }
    
    func timeString(_ interval: TimeInterval) -> String {
        let formatter = DateComponentsFormatter()
        formatter.unitsStyle = .positional
        formatter.allowedUnits = [.hour,.minute, .second]
        formatter.zeroFormattingBehavior = .pad
        return formatter.string(from: interval)!
    }
    
    private func startRecording() {
        if isPlaying {
            showHud(text: "请先停止播放!!")
            return
        }
        
        audioRecorder?.record()
        isRecording = true
        
        timer = Timer.scheduledTimer(withTimeInterval: timerInterval, repeats: true) { _ in
            recordingTime += timerInterval
        }
    }
    
    private func stopRecording() {
        audioRecorder?.stop()
        isRecording = false
        
        timer?.invalidate()
        timer = nil
        
        filePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("recording.caf").absoluteString
        //recordingTime = 0.0
    }
    
    func playRecording() {
        if isRecording {
            showHud(text: "请先停止录音!!")
            return
        }
        
        aup = try? AVAudioPlayer(contentsOf: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("recording.caf"))
        
        aup?.volume = 1;
        aup?.play()
        isPlaying = true
        timer = Timer.scheduledTimer(withTimeInterval: timerInterval, repeats: true) { _ in
            recordingTime -= timerInterval
            //print("\(recordingTime)")
            let num = String(format: "%.2f", recordingTime)
            if Double(num) ?? 0.0 < 0 {
                stopPlayback()
            }
        }
    }
    
    func stopPlayback() {
        aup?.stop()
        isPlaying = false
        
        timer?.invalidate()
        timer = nil
    }
}

struct PTRecording_Previews: PreviewProvider {
    static var previews: some View {
        PTRecording()
    }
}
